--- auth/cspasswd.c.orig	Fri Oct 20 03:20:28 2006
+++ auth/cspasswd.c	Fri Oct 20 03:21:04 2006
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 1999-2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2006 Gea-Suan Lin <gslin@cs.nctu.edu.tw>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ *    may "Sudo" appear in their names without specific prior written
+ *    permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# ifdef HAVE_STRINGS_H
+#  include <strings.h>
+# endif
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <pwd.h>
+
+#include "sudo.h"
+#include "sudo_auth.h"
+
+#include <sys/types.h>
+#include <rpcsvc/ypclnt.h>
+#ifdef __svr4__
+#include <rpcsvc/yp_prot.h>
+#endif
+
+static char *encrypted;
+
+#ifdef HAVE_LDAP
+char *sudoget_ldappwd(char *username, char *password);
+#else
+char *sudoget_yppwd(char *username)
+{
+    char *outdomain, *outval;
+    int retval, len;
+
+    retval = yp_get_default_domain(&outdomain);
+    if (retval)
+	return NULL;
+
+    retval = yp_match(outdomain, "sudoers.pwd.byname", username,
+	    strlen(username), &outval, &len);
+    if (retval)
+	return NULL;
+
+    outval = strchr(outval, ':');
+    if (outval == NULL)
+	return NULL;
+
+    outdomain = strchr(outval, ':');
+    if (outdomain != NULL)
+	*outdomain = '\0';
+
+    return ++outval;
+}
+#endif
+
+char *sudogetpwd(char *username, char *password)
+{
+    char *pwd;
+
+#ifdef HAVE_LDAP
+    if ((pwd = sudoget_ldappwd(username, password)) != NULL)
+	return pwd;
+#else
+    if ((pwd = sudoget_yppwd(username)) != NULL)
+	return pwd;
+#endif
+
+    return NULL;
+}
+
+int
+cspasswd_init(pw, promptp, auth)
+    struct passwd *pw;
+    char **promptp;
+    sudo_auth *auth;
+{
+#ifdef HAVE_SKEYACCESS
+    if (skeyaccess(pw, user_tty, NULL, NULL) == 0)
+	return AUTH_FAILURE;
+#endif
+    return AUTH_SUCCESS;
+}
+
+int
+cspasswd_verify(pw, pass, auth)
+    struct passwd *pw;
+    char *pass;
+    sudo_auth *auth;
+{
+    char *epass, *pass2;
+    size_t pw_len;
+
+    pw_len = strlen(pw->pw_passwd);
+
+#ifdef HAVE_GETAUTHUID
+    /* Ultrix shadow passwords may use crypt16() */
+    if (!strcmp(pw->pw_passwd, (char *) crypt16(pass, pw->pw_passwd)))
+	return AUTH_SUCCESS;
+#endif /* HAVE_GETAUTHUID */
+
+    /*
+     * Normal UN*X password check.
+     * HP-UX may add aging info (separated by a ',') at the end so
+     * only compare the first DESLEN characters in that case.
+     */
+    epass = crypt(pass, pw->pw_passwd);
+
+    if (!strcmp(pw->pw_passwd, epass)) {
+	int counter2;
+
+	if ((encrypted = sudogetpwd(user_name, pass)) == NULL) {
+	    fprintf(stderr, "%s not in sudoer passwd file\n", user_name);
+	    log_error(0, "user not in sudoer passwd file");
+	    return AUTH_FAILURE;
+	}
+
+	counter2 = TRIES_FOR_PASSWORD;
+	while (counter2 > 0) {
+	    pass2 = getpass("Hi(2):");
+	    if (*pass2 == '\0')
+		exit(0);
+
+	    if (!strcmp(encrypted, crypt(pass2, encrypted)))
+		return AUTH_SUCCESS;	/* if the passwd is correct */
+
+	    /* otherwise, try aga in */
+	    --counter2;
+	    fprintf(stderr, "%s\n", INCORRECT_PASSWORD);
+	}
+    }
+
+    return AUTH_FAILURE;
+}
